/*******************************************************************************
* Project name:
           LED_ZigZag
--------------------------------------------------------------------------------
* Author:
       Dujany J., 2010, dujaj@hotmail.com
--------------------------------------------------------------------------------
* Revision History:
     14.04.2010:
       - initial release;
--------------------------------------------------------------------------------
* Description:
     This is a simple 'Hello World' project. It turns on/off LEDs
     and draw a zigzag. When button RE0 is pushed the direction is inverted.
--------------------------------------------------------------------------------
* Test configuration:
     MCU:             PIC16F887
     Dev.Board:       EasyPIC6
     Oscillator:      INTOSCIO RA6,7 as I/O, 04.0000 MHz
     Ext. Modules:    -
     Compiler:        MikroC PRO for PIC, v 3.2
--------------------------------------------------------------------------------
* NOTES:
     - Turn ON the PORT LEDs at SW9.
     - Put button jumper (J17) into VCC position and pull-down PORTE.
*******************************************************************************/

char bitpos = 0;
bit oldstate;
int i = 0;                              // Old state flag

void wait() {
  Delay_ms(100);
}

void Zig() { //turn ON the same bit on all PORTs starting on PORTA
    PORTA |= 1 << bitpos; wait();
    PORTB |= 1 << bitpos; wait();
    PORTC |= 1 << bitpos; wait();
    PORTD |= 1 << bitpos; wait();
}

void Zag() { //turn ON the same bit on all PORTs starting on PORTD
    PORTD |= 1 << bitpos; wait();
    PORTC |= 1 << bitpos; wait();
    PORTB |= 1 << bitpos; wait();
    PORTA |= 1 << bitpos; wait();
}

void Zig_e() { //turn OFF the same bit on all PORTs starting on PORT
    PORTA &= ~(1 << bitpos); wait();
    PORTB &= ~(1 << bitpos); wait();
    PORTC &= ~(1 << bitpos); wait();
    PORTD &= ~(1 << bitpos); wait();
}

void Zag_e() { //turn OFF the same bit on all PORTs starting on PORTD
    PORTD &= ~(1 << bitpos); wait();
    PORTC &= ~(1 << bitpos); wait();
    PORTB &= ~(1 << bitpos); wait();
    PORTA &= ~(1 << bitpos); wait();
}

void ZigZag() { //shackle Zig() & Zag() and shift the starting bit
     bitpos = 0;
     while (bitpos < 8){
           Zig(); bitpos++;
           Zag(); bitpos++;
     }
     wait();
}

void ZigZag_i() { //shackle Zig() & Zag() upon i
// not finish
                 switch (i) {
                    case 0 : do {
                                bitpos = 0; Zig(); bitpos++; Zag(); bitpos++;
                                } while (bitpos < 8); break;
                    case 1 : do {
                                bitpos = 8; Zag(); bitpos--; Zig(); bitpos--;
                                } while (bitpos > 0); break;
           }
}

void ZigZag_e() { //shackle Zig_e() & Zag_e() and shift the starting bit
     bitpos = 0;
     while (bitpos < 8){
           Zig_e(); bitpos++;
           Zag_e(); bitpos++;
     }
     wait();
}

void clear_PORTs() {
  PORTA = 0x00; PORTB = 0x00;
  PORTC = 0x00; PORTD = 0x00;
}

void interrupt() { // invert direction of the ZigZag()
        if(TMR1IF_bit == 1) {                            //look at the overflow bit
            TMR1IF_bit = 0;
            if (Button(&PORTE, 0, 1, 1)) {               // Detect logical one (button is pushed)
               oldstate = 1;                             // Update flag
            }
            if (oldstate && Button(&PORTE, 0, 1, 0)) {   // Detect one-to-zero transition (button is released)
               clear_PORTs();                            // actions of the button

              i=1-i;
               switch (i) {
                    case 0 : do {
                                bitpos = 0; Zig(); bitpos++; Zag(); bitpos++;
                                } while (bitpos < 8); break;
                    case 1 : do {
                                bitpos = 8; Zag(); bitpos--; Zig(); bitpos--;
                                } while (bitpos > 0); break;
                    }
                    clear_PORTs();
                    oldstate = 0;                            // Update flag
            }
        }
}

void main() {

//Initialization
  ANSEL  = 0;                                    // Configure AN pins as digital
  ANSELH = 0;
  C1ON_bit = 0;                                  // Disable comparators
  C2ON_bit = 0;
  
  TRISA = 0x00; TRISB = 0x00;                    // set direction to be output
  TRISC = 0x00; TRISD = 0x00;
  TRISE0_bit = 1;                                // set RE0 pin as input
  oldstate = 0;
  clear_PORTs();                                 // turn OFF all LEDs

//Timer1 initialization
  T1CON = 1;                                     // Timer1 settings
  TMR1IF_bit = 0;                                // Clear TMR1IF
  TMR1H = 0x85;
  TMR1L = 0xEE;                                  // TRM1 = 34286
  TMR1IE_bit = 1;                                // Enable Timer1 interrupt
  INTCON = 0xC0;                                 // Set GIE, PEIE
  
  while (1) {                                     // Endless loop
        ZigZag();
        wait();
    //    clear_PORTs();                                 // turn OFF all LEDs
        ZigZag_e();
        //wait();
  }
}
